package com.dnjn.happiness.emo.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnjn.happiness.biz.api.RemoteEmotionTypeService;
import com.dnjn.happiness.common.amqp.AmqpSender;
import com.dnjn.happiness.common.core.constant.HappyConstants;
import com.dnjn.happiness.common.core.constant.SecurityConstants;
import com.dnjn.happiness.common.core.domain.R;
import com.dnjn.happiness.common.core.score.vo.HappyAiType;
import com.dnjn.happiness.common.core.score.vo.HappyVO;
import com.dnjn.happiness.common.core.model.EmotionTypeVO;
import com.dnjn.happiness.common.core.utils.StringUtils;
import com.dnjn.happiness.common.datascope.annotation.DataScope;
import com.dnjn.happiness.emo.api.RemoteEmoUserService;
import com.dnjn.happiness.emo.assist.FerAssist;
import com.dnjn.happiness.emo.domain.UserRecordFer;
import com.dnjn.happiness.emo.domain.vo.UserRecordFerExportVo;
import com.dnjn.happiness.emo.mapper.UserRecordFerMapper;
import com.dnjn.happiness.emo.service.IRanklistService;
import com.dnjn.happiness.emo.service.IUserRecordFerService;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;

/**
 * 用户AI情绪userRecordFerService业务层处理
 *
 * @author amber
 * @date 2023-12-04
 */
@Slf4j
@Service
public class UserRecordFerServiceImpl extends ServiceImpl<UserRecordFerMapper, UserRecordFer> implements IUserRecordFerService {


    

    @Autowired
    private IRanklistService ranklistService;

    @Autowired
    private FerAssist ferAssist;


    @Autowired
    private RemoteEmoUserService userService;

    @Autowired
    private RemoteEmotionTypeService emotionTypeService;

    @Override
    public Double getAIHappinessScores(Long userId, String time) {
        return baseMapper.getAIHappinessScores(userId, time);
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public Page<UserRecordFer> getPage(UserRecordFer userRecordFer, Page page) {
        return baseMapper.getPage(userRecordFer, page);
    }


    @Override
    public List<UserRecordFer> listAll(UserRecordFer userRecordFer) {
        return baseMapper.selectAll(userRecordFer);
    }

    @Override
    public Page<UserRecordFer> selectAi(Long userId, String emotionCode, String startTime, String endTime, Page page) {

        return baseMapper.selectAi(userId, emotionCode, startTime, endTime, page);
    }



    @Override
    public Page<UserRecordFer> selectAiPage(UserRecordFer vo, Page page) {
        return baseMapper.selectAiPage(vo, page);
    }

    @Override
    public boolean hasClockInYesterday(Long userId) {
        long count = lambdaQuery().eq(UserRecordFer::getUserId, userId)
                .eq(UserRecordFer::getDeleted, "0")
                .eq(UserRecordFer::getCurrDate, LocalDate.now().plusDays(-1))
                .count();
        return count > 0;
    }

    @Override
    public boolean removeByUserInfoAndCurrDate(Long userId, LocalDate currDate) {

        baseMapper.removeByUserInfoAndCurrDate(userId, currDate);
        return true;

    }

    @Override
    public List<UserRecordFer> selectStaleRecord() {

        return lambdaQuery()
                .eq(UserRecordFer::getDeleted, "0")
                .eq(UserRecordFer::getFerStatus, "0")
                .list();

    }

    @Override
    public boolean createOrUpdate(UserRecordFer record) {
        /*UserRecordFer po = lambdaQuery().eq(UserRecordFer::getUserId, record.getUserId())
                .eq(UserRecordFer::getCurrDate, record.getCurrDate())
                .one();
        if (po != null) {
            record.setFerId(record.getFerId());
        }*/
        Long todayClockInCount = lambdaQuery().eq(UserRecordFer::getUserId, record.getUserId())
                .eq(UserRecordFer::getCurrDate, record.getCurrDate()).count();
        boolean hasClockToday = Objects.nonNull(todayClockInCount) && todayClockInCount > 0;
        // added at 240201
        boolean hasClockInYesterday = hasClockInYesterday(record.getUserId());
        //每天一条记录
        removeByUserInfoAndCurrDate(record.getUserId(), record.getCurrDate());

        ranklistService.updateRecord(record.getUserId(), record.getNickName(), hasClockInYesterday);
        if (!hasClockToday) {
            R<Boolean> result = userService.updateWorkDate(record.getUserId(), SecurityConstants.INNER);
        }
        record.setFerCount(0);//
        boolean save = saveOrUpdate(record);
        // modify at 240314
        //SpringContextHolder.getBean(IUserRecordFerService.class).asyncFetchFer(record);
        return save;
    }



    @Override
    public void updateEmotionCode(List<UserRecordFer> recordFerList) {

        for (UserRecordFer el : recordFerList) {
            EmotionTypeVO emotionType = null;
            R<EmotionTypeVO> result = emotionTypeService.getByCode(el.getEmotionCode(),SecurityConstants.INNER);
            if (StringUtils.isNotNull(result) && StringUtils.isNotNull(result.getData())){
                emotionType = result.getData();
            }
            UserRecordFer record = getById(el.getFerId());
            record.setModScore(emotionType.getScore())
                    .setEmotionCode(emotionType.getCode())
                    .setEmotion(emotionType.getLabel())
                    .setFerCount(record.getFerCount() + 1)
                    .setFerStatus(2)
            ;
            saveOrUpdate(record);
            doCalcFerScore(record);
        }


    }

    @Override
    public void updateFerCountFailed(List<Long> unFerIdList) {
        if (unFerIdList.isEmpty()) {
            return;
        }
        lambdaUpdate().set(UserRecordFer::getFerStatus, 0)
                .setSql("fer_count = fer_count +1")
                .in(UserRecordFer::getFerId, unFerIdList)
                .update();
        //baseMapper.updateFerCountAndFerStatusUndo(unFerIdList);
    }


    @Deprecated
    @Override
    @Transactional(rollbackFor = Exception.class)
    @Async
    public void asyncFetchFer(UserRecordFer record) {
        log.info("fer {}", record.getImageUrl());
        String emotionCode = ferAssist.fetchFer(record.getImageUrl()).getEmo();
        if (StringUtils.isNotBlank(emotionCode)) {
            EmotionTypeVO emotionType = null;
            R<EmotionTypeVO> result = emotionTypeService.getByCode(emotionCode,SecurityConstants.INNER);
            if (StringUtils.isNotNull(result) && StringUtils.isNotNull(result.getData())){
                emotionType = result.getData();
            }
            record.setModScore(emotionType.getScore());
            record.setEmotionCode(emotionCode).setEmotion(emotionType.getLabel());
            saveOrUpdate(record);

            doCalcFerScore(record);

        }
    }




    private void doCalcFerScore(UserRecordFer record) {
        // todo -人脸影响快乐值
        HappyVO happyVO = new HappyVO();
        HappyAiType happyAi = new HappyAiType();
        happyAi.setAiType(record.getEmotionCode());
        happyVO.setRtype(HappyConstants.EMO_USER_RTYPE_AI);
        happyVO.setUserId(record.getUserId());
        happyVO.setAi(happyAi);
//        happyVO.setUserId(vo.getUserId());
        AmqpSender.sendArgs(happyVO);
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<UserRecordFerExportVo> getExportList(UserRecordFer vo) {
        List<UserRecordFerExportVo> exportList = baseMapper.getExportList(vo);
        return exportList;
    }



}
